package com.mofum.cloud.core.model.impl;

import com.mofum.cloud.core.error.device.memory.MemoryReadException;
import com.mofum.cloud.core.error.device.memory.MemoryWriteException;
import com.mofum.cloud.core.model.Memory;

import java.math.BigInteger;

/**
 * 标准内存实现
 *
 * @author yumi@omuao.com
 */
public class StandardMemoryImpl extends StandardDeviceImpl implements Memory {

    /**
     * 数据
     */
    private BigInteger[] data = null;

    /**
     * 位数
     */
    private int bit = BIT_8;

    /**
     * 8位
     */
    public static final short BIT_8 = 8;

    /**
     * 16位
     */
    public static final short BIT_16 = 16;

    /**
     * 32位
     */
    public static final short BIT_32 = 32;

    /**
     * 容量
     */
    private int capacity = 256;

    public StandardMemoryImpl() {
        this.init();
    }

    @Override
    public void init() {
        super.init();
        this.data = new BigInteger[capacity];
        for (int d = 0; d < data.length; d++) {
            data[d] = UNDEFINED;
        }
        this.putAbility(READ_SECTION_LEFT, UNDEFINED);
        this.putAbility(READ_SECTION_RIGHT, UNDEFINED);
        this.putAbility(WRITE_SECTION_LEFT, UNDEFINED);
        this.putAbility(WRITE_SECTION_RIGHT, UNDEFINED);
    }

    @Override
    public BigInteger read(BigInteger address) throws MemoryReadException {
        return data[address.intValue()];
    }

    @Override
    public void write(BigInteger address, BigInteger value) throws MemoryWriteException {
        BigInteger res = BigInteger.ZERO;
        for (int bit = 0; bit < this.bit; bit++) {
            res = res.setBit(bit);
        }
        data[address.intValue()] = value;
        if (value.compareTo(res) == 1) {
            data[address.intValue()] = res;
        }
    }

    @Override
    public BigInteger load(BigInteger address) throws MemoryReadException {
        return this.read(address);
    }

    @Override
    public BigInteger store(BigInteger address, BigInteger value) throws MemoryWriteException {
        return this.store(address, value);
    }

    @Override
    public BigInteger get(BigInteger address) throws MemoryReadException {
        return this.read(address);
    }

    @Override
    public BigInteger set(BigInteger address, BigInteger value) throws MemoryWriteException {
        return this.store(address, value);
    }

    public int getBit() {
        return bit;
    }

    public void setBit(int bit) {
        this.bit = bit;
    }

    public BigInteger[] getData() {
        return data;
    }

    public void setData(BigInteger[] data) {
        this.data = data;
    }

    public int getCapacity() {
        return capacity;
    }

    public void setCapacity(int capacity) {
        this.capacity = capacity;
    }
}
